syntax on
set number
set hlsearch
set incsearch
set ignorecase
set cursorline
set encoding=UTF-8
set scrolloff=5

noremap Q :q<CR>
"noremap <C-q> :qa<CR>
noremap S :w<CR>

map <Up> :res -5<CR>
map <Down> :res +5<CR>
map <Left> :vertical res -5<CR>
map <Right> :vertical res +5<CR>
" Set tabstop, softtabstop and shiftwidth to the same value
command! -nargs=* Stab call Stab()
function! Stab()
  let l:tabstop = 1 * input('set tabstop = softtabstop = shiftwidth = ')
  if l:tabstop > 0
    let &l:sts = l:tabstop
    let &l:ts = l:tabstop
    let &l:sw = l:tabstop
  endif
  call SummarizeTabs()
endfunction

function! SummarizeTabs()
  try
    echohl ModeMsg
    echon 'tabstop='.&l:ts
    echon ' shiftwidth='.&l:sw
    echon ' softtabstop='.&l:sts
    if &l:et
      echon ' expandtab'
    else
      echon ' noexpandtab'
    endif
  finally
    echohl None
  endtry
endfunction

" check if there's need to load machine_specific configuration, such as python
" interpreter path, local ip.
let has_machine_specific_file = 1
let specific_file_path = join([stdpath('config'), '/_machine_specific.vim'], '')
if empty(glob(specific_file_path))
      let has_machine_specific_file = 0
endif
set clipboard+=unnamedplus

" 插件配置
" 下面这个代理url有问题，无法正常访问
" let g:plug_url_format='https://git::@gitclone.com/github.com/%s.git'
let g:plug_url_format='https://hub.fastgit.xyz/%s.git'
call plug#begin('~/.local/share/nvim/plugged')
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
if has('nvim')
Plug 'scrooloose/nerdtree'
Plug 'numirias/semshi', { 'do': ':UpdateRemotePlugins' }
else
Plug 'preservim/nerdtree'
Plug 'jaxbot/semantic-highlight.vim'
endif
Plug 'Xuyuanp/nerdtree-git-plugin'
Plug 'neomake/neomake'
Plug 'mfussenegger/nvim-dap'
Plug 'jiangmiao/auto-pairs'
Plug 'scrooloose/nerdcommenter'
Plug 'sbdchd/neoformat'
Plug 'tmhedberg/SimpylFold'
Plug 'Yggdroot/LeaderF', { 'do': 'LeaderfInstallCExtension' }
Plug 'neoclide/coc.nvim', {'branch': 'release'}
Plug 'airblade/vim-gitgutter'
" Plug 'majutsushi/tagbar'
Plug 'morhetz/gruvbox'
Plug 'ryanoasis/vim-devicons'
Plug 'iamcco/markdown-preview.nvim', { 'do': { -> mkdp#util#install() }, 'for': ['markdown', 'vim-plug']}
Plug 'tpope/vim-fugitive'
Plug 'junegunn/gv.vim'
Plug 'SirVer/ultisnips'
Plug 'honza/vim-snippets'
Plug 'puremourning/vimspector', {'do': './install_gadget.py --enable-c --enable-python --enable-go'}
Plug 'mhinz/vim-startify'
Plug 'fatih/vim-go', { 'do': ':GoUpdateBinaries'  }
Plug 'voldikss/vim-translator'
Plug 'voldikss/vim-floaterm'
"Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
"Plug 'junegunn/fzf.vim'
Plug 'dhruvasagar/vim-table-mode'
Plug 'tpope/vim-surround'
Plug 'liuchengxu/vista.vim'
" go related
Plug 'fatih/vim-go'
Plug 'vimwiki/vimwiki'
Plug 'vim-pandoc/vim-pandoc'
call plug#end()
" let g:deoplete#enable_at_startup = 1
inoremap <expr><tab> pumvisible() ? "\<c-n>" : "\<tab>"
nnoremap <leader>f :Neoformat! python autopep8<CR>
let g:neomake_python_enabled_makers = ['pylint']
" 启用tab
let g:airline#extensions#tabline#enabled = 1
" 每个tab显示对应的buffer number 
let g:airline#extensions#tabline#buffer_nr_show = 1
let mapleader=","
"let g:Lf_ShortcutF = '<leader><leader>'

" disable autocompletion, cause we use deoplete for completion
" let g:jedi#completion_enabled=0
" open the go-to function in split, not another buffer
" let g:jedi#use_splits_not_buffers="right" 

" ==
" == leaderF
" == 
" todo check invalid command.
let g:Lf_ShortcutF = '<leader><leader>'
let g:Lf_WindowPosition = 'popup'
let g:Lf_PreviewInPopup = 1
let g:Lf_PreviewResult = {
    \ 'File': 1,
    \ 'Buffer': 1,
    \ 'Mru': 1,
    \ 'Tag': 1,
    \ 'BufTag': 1,
    \ 'Function': 1,
    \ 'Line': 1,
    \ 'Colorscheme': 1,
    \ 'Rg': 1,
    \ 'Gtags': 1
    \}
nnoremap <C-f> :Leaderf rg<CR>
nnoremap <leader>f :LeaderfFile<CR>

"nmap <leader>ar :TagbarToggle<CR>
"map <F5> :execute "cd" expand("%:h")<CR>
nmap tt :NERDTreeToggle<CR>
nnoremap <leader>L :NERDTreeFind<CR>
" Compile function
noremap rrr :call CompileRunGcc()<CR>
func! CompileRunGcc()
	exec "w"
	if &filetype == 'c'
		exec "!g++ % -o %<"
		exec "!time ./%<"
	elseif &filetype == 'cpp'
		set splitbelow
		exec "!g++ -std=c++11 % -Wall -o %<"
		:sp
		:res -15
		:term ./%<
	elseif &filetype == 'java'
		exec "!javac %"
		exec "!time java %<"
	elseif &filetype == 'sh'
		:!time bash %
	elseif &filetype == 'python'
		set splitbelow
		:sp
		:term python3 %
	elseif &filetype == 'html'
		silent! exec "!".g:mkdp_browser." % &"
	elseif &filetype == 'markdown'
		exec "MarkdownPreview"
	elseif &filetype == 'tex'
		silent! exec "VimtexStop"
		silent! exec "VimtexCompile"
	elseif &filetype == 'dart'
		CocCommand flutter.run -d iPhone\ 11\ Pro
		CocCommand flutter.dev.openDevLog
	elseif &filetype == 'javascript'
		set splitbelow
		:sp
		:term export DEBUG="INFO,ERROR,WARNING"; node --trace-warnings .
	elseif &filetype == 'go'
		set splitbelow
		:sp
		:term go run .
	endif
endfunc
" -------------------------------------------------------------------------------------------------
" coc.nvim default settings
" -------------------------------------------------------------------------------------------------

" if hidden is not set, TextEdit might fail.
set hidden
" Better display for messages
set cmdheight=2
" Smaller updatetime for CursorHold & CursorHoldI
set updatetime=300
" don't give |ins-completion-menu| messages.
set shortmess+=c
" always show signcolumns
set signcolumn=yes

" Use tab for trigger completion with characters ahead and navigate.
" Use command ':verbose imap <tab>' to make sure tab is not mapped by other plugin.
inoremap <silent><expr> <TAB>
      \ pumvisible() ? "\<C-n>" :
      \ <SID>check_back_space() ? "\<TAB>" :
      \ coc#refresh()
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"

function! s:check_back_space() abort
  let col = col('.') - 1
  return !col || getline('.')[col - 1]  =~# '\s'
endfunction

" Use <c-space> to trigger completion.
inoremap <silent><expr> <c-space> coc#refresh()

" Use `[c` and `]c` to navigate diagnostics
nmap <silent> [c <Plug>(coc-diagnostic-prev)
nmap <silent> ]c <Plug>(coc-diagnostic-next)

nnoremap <silent> <space>y :<C-u>CocList -A --normal yank<cr>

" Remap keys for gotos
nmap <silent> gd <Plug>(coc-definition)
nmap <silent> gy <Plug>(coc-type-definition)
nmap <silent> gi <Plug>(coc-implementation)
nmap <silent> gr <Plug>(coc-references)

" Use U to show documentation in preview window
nnoremap <silent> U :call <SID>show_documentation()<CR>

" Remap for rename current word
nmap <leader>rn <Plug>(coc-rename)

" Remap for format selected region
vmap <leader>f  <Plug>(coc-format-selected)
nmap <leader>f  <Plug>(coc-format-selected)
" Show all diagnostics
nnoremap <silent> <space>a  :<C-u>CocList diagnostics<cr>
" Manage extensions
nnoremap <silent> <space>e  :<C-u>CocList extensions<cr>
" Show commands
nnoremap <silent> <space>c  :<C-u>CocList commands<cr>
" Find symbol of current document
nnoremap <silent> <space>o  :<C-u>CocList outline<cr>
" Search workspace symbols
nnoremap <silent> <space>s  :<C-u>CocList -I symbols<cr>
" Do default action for next item.
nnoremap <silent> <space>j  :<C-u>CocNext<CR>
" Do default action for previous item.
nnoremap <silent> <space>k  :<C-u>CocPrev<CR>
" Resume latest coc list
nnoremap <silent> <space>p  :<C-u>CocListResume<CR>
" ==
" == coc custom settings
" ==
let g:coc_global_extensions = ['coc-python', 'coc-vimlsp', 'coc-html', 'coc-json', 'coc-css', 'coc-tsserver', 'coc-yank', 'coc-lists', 'coc-git', 'coc-pyright', 'coc-todolist', 'coc-diagnostic', "coc-prettier"]

" ==
" == GitGutter
" ==
let g:gitgutter_signs = 0
let g:gitgutter_map_keys = 0
let g:gitgutter_override_sign_column_highlight = 0
let g:gitgutter_preview_win_floating = 1
autocmd BufWritePost * GitGutter
nnoremap <LEADER>gf :GitGutterFold<CR>
nnoremap H :GitGutterPreviewHunk<CR>
nnoremap gg- :GitGutterPrevHunk<CR>
nnoremap gg= :GitGutterNextHunk<CR>
colorscheme gruvbox
set background=dark " use dark mode    
" set background=light " uncomment to use light mode
if has("win32")
set guifont=DroidSansMono\ NF:11
else
set guifont=Droid\ Sans\ Mono\ Nerd\ Font\ Mono\ 11
endif
" Markdown related map
nmap <C-s> <Plug>MarkdownPreview
nmap <M-s> <Plug>MarkdownPreviewStop
nmap <C-p> <Plug>MarkdownPreviewToggle

" ==
" == ultisnips
" ==
let g:UltiSnipsExpandTrigger="<c-e>"
let g:UltiSnipsJumpForwardTrigger="<c-b>"
let g:UltiSnipsJumpBackwardTrigger="<c-z>"

" ==
" == vim-translator
" ==
" Echo translation in the cmdline
nmap <silent> <Leader>t <Plug>Translate
vmap <silent> <Leader>t <Plug>TranslateV
" Display translation in a window
nmap <silent> <Leader>w <Plug>TranslateW
vmap <silent> <Leader>w <Plug>TranslateWV
" Replace the text with translation
nmap <silent> <Leader>r <Plug>TranslateR
vmap <silent> <Leader>r <Plug>TranslateRV
" Translate the text in clipboard
nmap <silent> <Leader>x <Plug>TranslateX

" ==
" == vim-floaterm
" ==
" Configuration example
let g:floaterm_keymap_new    = '<F7>'
let g:floaterm_keymap_prev   = '<F8>'
let g:floaterm_keymap_next   = '<F9>'
"let g:floaterm_keymap_toggle = '<F12>'
let g:floaterm_keymap_toggle = ',e'
let g:floaterm_wintype = 'floating'
let g:floaterm_gitcommit = 'vsplit'
let g:floaterm_autoclose = 2
let g:floaterm_width = 0.9
let g:floaterm_height = 0.9

" ===
" === FZF
" ===
"noremap <C-p> :Files<CR>
"noremap ,, :Files<CR>
"noremap <C-f> :Ag<CR>
"noremap <C-h> :History<CR>
"noremap <C-t> :BTags<CR>
"noremap <C-l> :Lines<CR>

"let g:fzf_preview_window = 'right:60%'
"let g:fzf_commits_log_options = '--graph --color=always --format="%C(auto)%h%d %s %C(black)%C(bold)%cr"'

function! s:list_buffers()
  redir => list
  silent ls
  redir END
  return split(list, "\n")
endfunction

function! s:delete_buffers(lines)
  execute 'bwipeout' join(map(a:lines, {_, line -> split(line)[0]}))
endfunction

command! BD call fzf#run(fzf#wrap({
  \ 'source': s:list_buffers(),
  \ 'sink*': { lines -> s:delete_buffers(lines) },
  \ 'options': '--multi --reverse --bind ctrl-a:select-all+accept'
\ }))

"noremap <c-d> :BD<CR>
"noremap ,b :BD<CR>

"let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.8 } }

" ===
" === vimspector
" ===
let g:vimspector_enable_mappings = 'HUMAN'
function! s:read_template_into_buffer(template)
	" has to be a function to avoid the extra space fzf#run insers otherwise
	execute '0r ~/.config/nvim/sample_vimspector_json/'.a:template
endfunction
command! -bang -nargs=* LoadVimSpectorJsonTemplate call fzf#run({
			\   'source': 'ls -1 ~/.config/nvim/sample_vimspector_json',
			\   'down': 20,
			\   'sink': function('<sid>read_template_into_buffer')
			\ })
"noremap <leader>vs :tabe .vimspector.json<CR>:LoadVimSpectorJsonTemplate<CR>
" remember add .vimspector.json to project root for using, which content can
" reuse configuration file below.
noremap <leader>vs :tabe ~/.config/nvim/sample_vimspector_json/python.json
sign define vimspectorBP text=☛ texthl=Normal
sign define vimspectorBPDisabled text=☞ texthl=Normal
sign define vimspectorPC text=🔶 texthl=SpellBad
nmap <F5> <Plug>VimspectorContinue
let g:vimspector_install_gadgets = ['debugpy', 'vscode-go']

" load machine specific configuration
if has_machine_specific_file == 1
	exec join(["source ", stdpath('config'), "/_machine_specific.vim"], '')
endif

" ==
" == markdown preview
" ==

let g:mkdp_open_to_the_world = 1
let g:mkdp_port = 8080
function! g:EchoUrl(url)
	:echo a:url
endfunction
"use custom browserfunc only if ip is set and not equals local machine.
if (g:mkdp_open_ip == '127.0.0.1') || (g:mkdp_open_ip == '')
	let g:mkdp_browserfunc = ''
else
	let g:mkdp_browserfunc = 'g:EchoUrl'
endif


let markdown_path = join([stdpath('config'), '/md-snippets.vim'], '')
if !empty(glob(markdown_path)) 
	exec join(["source ", markdown_path], '')
	echo "loading markdown snippets."
endif
" auto spell
autocmd BufRead,BufNewFile *.md setlocal spell
	
" =
" = table-mode
" =
let g:table_mode_corner='|'


" =
" = vista.vim
" =
" How each level is indented and what to prepend.
" This could make the display more compact or more spacious.
" e.g., more compact: ["▸ ", ""]
" Note: this option only works the LSP executives, doesn't work for `:Vista ctags`.
let g:vista_icon_indent = ["╰─▸ ", "├─▸ "]

" Executive used when opening vista sidebar without specifying it.
" See all the avaliable executives via `:echo g:vista#executives`.
let g:vista_default_executive = 'ctags'

" Set the executive for some filetypes explicitly. Use the explicit executive
" instead of the default one for these filetypes when using `:Vista` without
" specifying the executive.
let g:vista_executive_for = {
  \ 'cpp': 'vim_lsp',
  \ 'php': 'vim_lsp',
  \ }

" Declare the command including the executable and options used to generate ctags output
" for some certain filetypes.The file path will be appened to your custom command.
" For example:
let g:vista_ctags_cmd = {
      \ 'haskell': 'hasktags -x -o - -c',
      \ }

" Ensure you have installed some decent font to show these pretty symbols, then you can enable icon for the kind.
let g:vista#renderer#enable_icon = 1

" The default icons can't be suitable for all the filetypes, you can extend it as you wish.
let g:vista#renderer#icons = {
\   "function": "\uf794",
\   "variable": "\uf71b",
\  }
let g:vista_echo_cursor_strategy = 'floating_win'
noremap <LEADER>v :Vista coc<CR>
noremap <LEADER>ar :Vista!!<CR>

" =
" = vimwiki
" =
let g:vimwiki_list = [{'path': '~/vimwiki/',
                      \ 'syntax': 'markdown', 'ext': '.md'}]
let g:vimwiki_diary_months = {
      \ 1: '一月', 2: '二月', 3: '三月',
      \ 4: '四月', 5: '五月', 6: '六月',
      \ 7: '七月', 8: '八月', 9: '九月',
      \ 10: '十月', 11: '十一月', 12: '十二月'
      \ }
"nmap <leader>qt :!/usr/lib/x86_64-linux-gnu/qt5/bin/designer<CR>

function! Start_qt()
	let l:current_path = expand("%:p:h")
	let l:argument=join(['!cd "', l:current_path, '" && nohup /usr/lib/x86_64-linux-gnu/qt5/bin/designer &'], '')
	"let l:command="cd %(path)s && /usr/lib/x86_64-linux-gnu/qt5/bin/designer" % {'path': l:current_path}
	"echo l:argument
	exec l:argument
endfunction

nmap <leader>qt :call Start_qt()<CR>

function! PyUic()
	let l:current_path = expand("%:p:h")
	"$FileName$ -o $FileNameWithoutExtension$.py
	let l:command = join(['!cd "', l:current_path, '" && /usr/bin/pyuic5 "', expand('%:t'),'" -o ', expand('%:t:r'), '.py'], '')
	echom l:command
	exec l:command
	echom 'pyuic transform finished!'
endfunction

nmap <leader>qy :call PyUic()<CR>

" go related
"
let g:go_fmt_command = 'goimports'
let g:go_autodetect_gopath = 1
" let g:go_bin_path = '$GOBIN'
"
let g:go_highlight_types = 1
let g:go_highlight_fields = 1
let g:go_highlight_functions = 1
let g:go_highlight_function_calls = 1
let g:go_highlight_extra_types = 1
let g:go_highlight_generate_tags = 1

" Open :GoDeclsDir with ctrl-g
nmap <C-g> :GoDeclsDir<cr>
imap <C-g> <esc>:<C-u>GoDeclsDir<cr>

augroup go
 autocmd!
 autocmd BufNewFile,BufRead *.go setlocal noexpandtab tabstop=4 shiftwidth=4
augroup END

